package com.example.anjia03_3z.controller;


import com.example.anjia03_3z.exception.ServiceException;
import com.example.anjia03_3z.web.JsonResult;
import com.example.anjia03_3z.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandle {

    @ExceptionHandler
    public JsonResult<Void> handleServiceException(ServiceException e) {
        return JsonResult.fail(e.getServiceCode(),e.getMessage());
    }


    @ExceptionHandler
    public JsonResult<Void> handleBindException(BindException e) {
        //配置快速失败后只会出现一个错误故而使用此方法 抛出异常信息
        String message = e.getFieldError().getDefaultMessage();

//        源码基于StringBuilder 不具有线程安全 效率较高

//        StringJoiner stringJoiner = new StringJoiner(",","内容不能为空","! ! !");
//        List<FieldError> fieldErrors = e.getFieldErrors();
//        for (FieldError fieldError : fieldErrors) {
//            String defaultMessage = fieldError.getDefaultMessage();
//            stringJoiner.add(defaultMessage);
//        }
        return JsonResult.fail(ServiceCode.ERR_BAD_REQUEST, message);
    }

    @ExceptionHandler
    public JsonResult<Void> handleConstraintViolationException(ConstraintViolationException e) {
        String message = null;
        /*配置快速失败后只会捕捉一个错误*/
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            message = constraintViolation.getMessage();
        }
        return JsonResult.fail(ServiceCode.ERR_BAD_REQUEST, message);
    }


    /*项目中必须存在throwable 但是会使得错误不明显*/
    /*此方法不是处理异常的最优解 ，仅是防止用户获取错误信息的*/
    @ExceptionHandler
    //若添加该方法则所有错误会返回该异常的后台信息（已发现400 404 等报错）
    public JsonResult<Void> handleThrowable(Throwable e) {
        String message= "服务器异常，需要检查响应信息并处理";
        log.warn("异常类型: {}",e.getClass().getName());
        log.warn("异常信息: {}",e.getMessage());
        log.warn("异常跟踪信息:",e);
//        e.printStackTrace();/*获取异常的跟踪信息并打印在运行窗口中 效率较低 资源阻塞*/
        return JsonResult.fail(ServiceCode.ERR_UNKNOWN,message);
    }
}
